package org.app.appjson;

import org.app.appjson.reader.JsonLexer;
import org.app.appjson.reader.JsonParser;
import org.app.appjson.reader.ReadHandler;
import org.app.appjson.writer.WriteHandler;
import org.app.appjson.exception.AppJsonException;
import org.app.appjson.reader.charreader.BufferedCharReader;
import org.app.appjson.reader.charreader.StringReader;
import org.app.appjson.reader.jsonnode.JsonNode;

import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;

/**
 * AppJson
 * 门面模式，简单的API接口
 * @author lizhongsi
 * @version 1.0
 * @since 1.0
 */
public class AppJson {

    /* -------------------------------------------------------------------------
     * json转对象
     ------------------------------------------------------------------------- */

    /**
     * 读取字符串的JSON流式解析器
     * @param lexer 词法分析器
     * @param classes 目标类型
     * @return 返回对象
     * @param <T> 泛型参数
     * @throws AppJsonException 异常
     */
    private static <T> T fromJson(JsonLexer lexer, final Class<?>... classes) throws AppJsonException {
        ReadHandler handler = new ReadHandler(lexer, classes);
        return handler.doRead();
    }

    public static <T> T fromJson(final String json, final Class<?>... classes) throws AppJsonException {
        JsonLexer lexer = new JsonLexer(new StringReader(json));
        return fromJson(lexer, classes);
    }

    public static <T> T fromJson(final Reader in, final Class<?>... classes) throws AppJsonException {
        JsonLexer lexer = new JsonLexer(new BufferedCharReader(in));
        return fromJson(lexer, classes);
    }

    /* -------------------------------------------------------------------------
     * 对象转json
     ------------------------------------------------------------------------- */

    /**
     * 返回JSON字符串
     * @param object 对象
     * @param writer 写出流
     * @return json字符出
     */
    public static String toJson(final Object object, final Writer writer) throws AppJsonException {
        WriteHandler handler = new WriteHandler(writer, object);
        return handler.doWrite();
    }

    public static String toJson(final Object object) throws AppJsonException {
        StringWriter writer = new StringWriter();
        return toJson(object, writer);
    }

    /* -------------------------------------------------------------------------
     * 获取json节点
     ------------------------------------------------------------------------- */

    /**
     * 读取json字符串，并返回指定一级节点
     * eg: AppJson.getNode(json, "name");
     * @param json json字符串
     * @return 节点对象
     */
    public static JsonNode getJsonNode(String json) throws AppJsonException {
        JsonLexer lexer = new JsonLexer(new StringReader(json));
        JsonParser parser = new JsonParser(lexer);
        return new JsonNode(parser.parse());
    }

    /**
     * 缓冲读取json字符流，并返回指定一级节点
     * @param in json字符流
     * @return 节点对象
     */
    public static JsonNode getJsonNode(Reader in) throws AppJsonException {
        JsonLexer lexer = new JsonLexer(new BufferedCharReader(in));
        JsonParser parser = new JsonParser(lexer);
        return new JsonNode(parser.parse());
    }

}
